package org.kinglone.utlis;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.springframework.util.Assert;

/**
 * 
 * 名称： DateUtils <br>
 * 描述：
 * 
 */
public abstract class DateUtils {

	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

	public static final String DEFAULT_TIME_ZONE = "GMT+8:00";

	public static final String NORMAL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

	public static Date toDate(String string) {
		return toDate(string, DEFAULT_DATE_FORMAT);
	}

	public static Date toDate(String string, String pattern) {
		return toDate(string, pattern, TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
	}

	public static Date toDate(String string, String pattern, TimeZone timeZone) {
		try {
			SimpleDateFormat sdf = (SimpleDateFormat) createDateFormat(pattern, timeZone);
			return sdf.parse(string);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	public static String format(Date date, String pattern, TimeZone timeZone) {
		DateFormat df = createDateFormat(pattern, timeZone);
		return df.format(date);
	}

	/**
	 * <p>
	 * Description: 根据指定的pattern格式化date
	 * </p>
	 * 字母 日期或时间元素 表示 示例 <br>
	 * G Era 标志符 Text AD <br>
	 * y 年 Year 1996; 96 <br>
	 * M 年中的月份 Month July; Jul; 07 <br>
	 * w 年中的周数 Number 27 <br>
	 * W 月份中的周数 Number 2 <br>
	 * D 年中的天数 Number 189 <br>
	 * d 月份中的天数 Number 10 <br>
	 * F 月份中的星期 Number 2 <br>
	 * E 星期中的天数 Text Tuesday; Tue <br>
	 * a Am/pm 标记 Text PM <br>
	 * H 一天中的小时数（0-23） Number 0 <br>
	 * k 一天中的小时数（1-24） Number 24 <br>
	 * K am/pm 中的小时数（0-11） Number 0 <br>
	 * h am/pm 中的小时数（1-12） Number 12 <br>
	 * m 小时中的分钟数 Number 30 <br>
	 * s 分钟中的秒数 Number 55 <br>
	 * S 毫秒数 Number 978 <br>
	 * z 时区 General time zone Pacific Standard Time; PST; GMT-08:00 <br>
	 * Z 时区 RFC 822 time zone -
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String format(Date date, String pattern) {
		DateFormat df = createDateFormat(pattern);
		return df.format(date);
	}

	public static DateFormat createDateFormat(String pattern) {
		return createDateFormat(pattern, TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
	}

	public static DateFormat createDateFormat(String pattern, TimeZone timeZone) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		TimeZone gmt = timeZone;
		sdf.setTimeZone(gmt);
		sdf.setLenient(true);
		return sdf;
	}

	public static int getYear(java.util.Date date) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR);
	}

	public static String getShortYear(java.util.Date date) {
		String year = getYear(date) + "";
		int length = year.length();
		return year.substring(length - 2, length);
	}

	public static int getMonth(java.util.Date date) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH) + 1;
	}

	public static int getDay(java.util.Date date) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	public static int getHour(java.util.Date date) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(date);
		return calendar.get(Calendar.HOUR_OF_DAY);
	}

	public static int getMinute(java.util.Date date) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(date);
		return calendar.get(Calendar.MINUTE);
	}

	public static int getSecond(java.util.Date date) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(date);
		return calendar.get(Calendar.SECOND);
	}

	public static Date addMilliSecond(java.util.Date oldDate, int addMilliSecond) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.add(Calendar.MILLISECOND, addMilliSecond);
		return calendar.getTime();
	}

	public static Date addSecond(java.util.Date oldDate, int addSecond) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.add(Calendar.SECOND, addSecond);
		return calendar.getTime();
	}

	public static Date addMinute(java.util.Date oldDate, int addMinutes) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.add(Calendar.MINUTE, addMinutes);
		return calendar.getTime();
	}

	public static Date addHour(java.util.Date oldDate, int addHours) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.add(Calendar.HOUR, addHours);
		return calendar.getTime();
	}

	public static Date addDay(java.util.Date oldDate, int addDays) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.add(Calendar.DATE, addDays);
		return calendar.getTime();
	}

	public static Date addMonth(java.util.Date oldDate, int addMonths) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.add(Calendar.MONTH, addMonths);
		return calendar.getTime();
	}

	public static Date addYear(java.util.Date oldDate, int addYears) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.add(Calendar.YEAR, addYears);
		return calendar.getTime();
	}

	public static long calcTimeBetween(String unitType, Date startDate, Date endDate) {
		Assert.hasText(unitType);
		Assert.notNull(startDate);
		Assert.notNull(endDate);
		long between = endDate.getTime() - startDate.getTime();
		if (unitType.equals("ms")) {
			return between;
		} else if (unitType.equals("s")) {
			return between / 1000;// 返回秒
		} else if (unitType.equals("m")) {
			return between / 60000;// 返回分钟
		} else if (unitType.equals("h")) {
			return between / 3600000;// 返回小时
		} else if (unitType.equals("d")) {
			return between / 86400000;// 返回天数
		} else {
			throw new IllegalArgumentException("the unitType is unknown");
		}
	}

	public static long calcTimeBetweenInMillis(Date startDate, Date endDate) {
		return calcTimeBetween("ms", startDate, endDate);
	}

	public static long calcTimeBetweenInSecond(Date startDate, Date endDate) {
		return calcTimeBetween("s", startDate, endDate);
	}

	public static long calcTimeBetweenInMinute(Date startDate, Date endDate) {
		return calcTimeBetween("m", startDate, endDate);
	}

	public static long calcTimeBetweenInHour(Date startDate, Date endDate) {
		return calcTimeBetween("h", startDate, endDate);
	}

	public static long calcTimeBetweenInDay(Date startDate, Date endDate) {
		return calcTimeBetween("d", startDate, endDate);
	}

	public static Date roundYear(Date date) {
		return org.apache.commons.lang.time.DateUtils.round(date, Calendar.YEAR);
	}

	public static Date roundMonth(Date date) {
		return org.apache.commons.lang.time.DateUtils.round(date, Calendar.MONTH);
	}

	public static Date roundDay(Date date) {
		return org.apache.commons.lang.time.DateUtils.round(date, Calendar.DATE);
	}

	public static Date roundHour(Date date) {
		return org.apache.commons.lang.time.DateUtils.round(date, Calendar.HOUR);
	}

	public static Date roundMinute(Date date) {
		return org.apache.commons.lang.time.DateUtils.round(date, Calendar.MINUTE);
	}

	public static Date roundSecond(Date date) {
		return org.apache.commons.lang.time.DateUtils.round(date, Calendar.SECOND);
	}

	public static Date truncateYear(Date date) {
		return org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.YEAR);
	}

	public static Date truncateMonth(Date date) {
		return org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.MONTH);
	}

	public static Date truncateDay(Date date) {
		return org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DATE);
	}

	public static Date truncateHour(Date date) {
		return org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.HOUR);

	}

	public static Date truncateMinute(Date date) {
		return org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.MINUTE);
	}

	public static Date truncateSecond(Date date) {
		return org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.SECOND);
	}

	public static Date setHour(Date oldDate, int newHour) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.set(Calendar.HOUR, newHour);
		return calendar.getTime();
	}

	public static Date setMinute(Date oldDate, int newMinute) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.set(Calendar.MINUTE, newMinute);
		return calendar.getTime();
	}

	public static Date setSecond(Date oldDate, int newSecond) {
		Calendar calendar = (Calendar) Calendar.getInstance().clone();
		calendar.setTime(oldDate);
		calendar.set(Calendar.SECOND, newSecond);
		return calendar.getTime();
	}

	/**
	 * 
	 * @param dt
	 *          Date
	 * @return boolean
	 */
	@SuppressWarnings("deprecation")
	public static boolean isRYear(Date dt) {
		return (isRYear(1900 + dt.getYear()));
	}

	/**
	 * 
	 * @param y
	 *          int
	 * @return boolean
	 */
	public static boolean isRYear(int y) {
		return (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0));
	}

	/**
	 * 获取一个日期的时间字符串
	 * 
	 * @param dt
	 *          Date
	 * @return String
	 */
	public static String getTimeStr(Date dt) {
		return new SimpleDateFormat("HH:mm:ss").format(dt);
	}

	/**
	 * 获取一个日期值的日期字符串
	 * 
	 * @param dt
	 *          Date
	 * @return String
	 */
	public static String getDateStr(Date dt) {
		return new SimpleDateFormat("yyyy-MM-dd").format(dt);
	}

	/**
	 * 获取一个日期值的带时间日期字符串
	 * 
	 * @param dt
	 *          Date
	 * @return String
	 */
	public static String getLongDate(Date dt) {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dt);
	}

	/**
	 * 
	 * @param dt
	 *          Date
	 * @return String
	 */
	public static String toString(Date dt) {
		return format(dt, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 获取当前时间搓 格式 yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getCurTstamp(){
		return toString(new Date());
	}
	
	/**
	 * 
	 * @param date
	 *          Date
	 * @return Timestamp added by jiayc
	 */
	public static java.sql.Timestamp dateToTimeStamp(java.util.Date date) {
		if (date == null) {
			return null;
		} else {
			return new java.sql.Timestamp(date.getTime());
		}
	}

	/**
	 * @param oldTime
	 *          较小的时间
	 * @param newTime
	 *          较大的时间 (如果为空 默认当前时间 ,表示和当前时间相比)
	 * @return true or false
	 * @throws ParseException
	 *           转换异常
	 */
	public static boolean isToday(Date oldTime, Date newTime) {
		if (newTime == null) {
			newTime = new Date();
		}
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String oldTimeStr = format.format(oldTime);
		String newTimeStr = format.format(newTime);
		if (newTimeStr.equals(oldTimeStr)) {
			return true;
		} else {
			return false;
		}
	}
}
